﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using Framework.Core;
using Framework.Core.BootStrapper.WindowsService;
using Framework.Core.Io;
using Framework.Remoting.Conventions;
using log4net;

namespace Framework.Remoting.Hosting
{
    public class WcfHost : WcfHost<WindowsServiceArgs>
    {

    }

    public class WcfHost<TArgs> : WindowsServicePlugin<TArgs>
        where TArgs : WindowsServiceArgs
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof (WcfHost<TArgs>));

        internal WcfHost(IServiceHostFactory<ServiceHost> serviceHostFactory, IAssemblyAdapter assemblyAdapter)
        {
            this.serviceHostFactory = serviceHostFactory;
            this.assemblyAdapter = assemblyAdapter;
        }

        public WcfHost()
            : this(new ServiceHostFactory(new WcfServiceInfoFactory(new ConfigurationManagerAdapter(), new BindingFactory(), new ProtocolFactory())), new AssemblyAdapter())
        {
            
        }

        internal List<ServiceHost> Hosts { get; private set; }

        private readonly IServiceHostFactory<ServiceHost> serviceHostFactory;

        private readonly IAssemblyAdapter assemblyAdapter;

        internal IEnumerable<Type> GetServices()
        {
            return assemblyAdapter.GetEntryAssembly()
                .GetTypes()
                .Where(t => t.HasCustomAttribute<ServiceContractAttribute>() && !t.IsInterface);
        }

        public override void Start(TArgs args)
        {
            Hosts = new List<ServiceHost>();

            GetServices().ToList().ForEach(t =>
            {
                var host = serviceHostFactory.Create(t, args.Environment);
                Hosts.Add(host);
            });
        }

        public override void Stop()
        {
            Logger.Info("Stopping All Hosts");

            Hosts.ForEach(h => serviceHostFactory.Close(h));
        }
    }
}